﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Expect.Core.Interfaces;
using Expect.Core.Helpers;

namespace Expect.Core.Fixtures
{
    /// <summary>
    /// Fixture class for fixture methods with data
    /// </summary>
    public class MethodWithFixtureDataFixture : AbstractFixture, ITableFixtureFormat
    {
        private FixtureData data = new FixtureData();

        private List<string> definition;

        /// <summary>
        /// Execute the fixture for the provided row
        /// </summary>
        public override bool? RunRow()
        {
            if (definition == null)
            {
                definition = new List<string>();
                foreach (var cell in Row.Cells)
                {
                    definition.Add(cell.Text);
                }
            }
            else
            {
                data.Add(Row.GetRowData(definition));
            }

            return true;
        }

        /// <summary>
        /// Called when there is no more rows to process
        /// </summary>
        public override void EndRun()
        {
            if (Specification.HasImplementation)
            {
                bool? resSpec = Context.RunAsFluentFixtureMethod(Specification.Implementation, Fixture, Fixture.Definition);
                if (resSpec.HasValue && resSpec.Value)
                {
                    SetFixtureSuccess(); 
                    return;
                }
            }

            if (Context.Container != null)
            {
                bool? res = Context.RunAsFluentFixtureMethod(Context.Container, Fixture, Fixture.Definition);
                if (res.HasValue && res.Value)
                {
                    SetFixtureSuccess();
                    return;
                }
            }
        }

        private void SetFixtureSuccess()
        {
            foreach (var row in Fixture.Rows)
            {
                foreach (var cell in row.Cells)
                {
                    if (!cell.Status.Success.HasValue) cell.Status.Success = true;
                }
                row.CalculateResult();
            }
            Fixture.CalculateResult();
        }
    }
}
